Popular Searches
Popular Course Categories
Popular Courses

Handling Notification Events, Deep Links, and Universal Links

Handling Notification Events, Deep Links, and Universal Links

Background Tasks, Push Notifications, and App Services

Handling Notification Events, Deep Links, and Universal Links in iOS

Course: iOS App Development

Topic: Handling Notification Events, Deep Links, and Universal Links

Course Link: iOS App Development Training

Demo Link: Register for Course Demo

Website: JustAcademy


1. Introduction

Modern iOS applications use notifications and links to help users access important information quickly. Notifications inform users about events such as new messages, order updates, reminders, and account activity. Deep links and Universal Links allow users to open a particular screen or resource inside an application instead of navigating manually.

For example, when a user taps a notification about a new message, the application can open the relevant conversation. When a user taps a link to a product on a website, the installed application can open that product's detail screen.

iOS provides the UserNotifications framework, URL handling APIs, Associated Domains, and SwiftUI navigation features to implement these experiences.

Learning Objectives

  • Understand local and remote notifications.
  • Configure notification permissions and categories.
  • Handle notification events in foreground and background situations.
  • Process notification action buttons and response payloads.
  • Understand custom URL schemes and deep linking.
  • Configure and implement Universal Links.
  • Handle URLs in UIKit and SwiftUI applications.
  • Navigate to specific application screens from notifications and links.
  • Validate incoming URLs and protect sensitive application data.

2. Understanding iOS Notifications

A notification is an alert or information message delivered by an application to communicate with the user. Notifications can appear on the Lock Screen, Notification Center, banners, and other supported system interfaces.

iOS supports two major types of application notifications.

Notification Type Description Example
Local Notification Created and scheduled directly by the application. Medication reminder or task reminder.
Remote Notification Sent from a server through Apple Push Notification service (APNs). New chat message or delivery update.

Local Notification Flow

  1. The application creates notification content.
  2. The application creates a notification trigger.
  3. A notification request is submitted to the notification center.
  4. iOS schedules the notification.
  5. The system delivers it when the trigger conditions are met.
  6. The user can view or interact with the notification.

Remote Notification Flow

  1. The application requests permission to display notifications.
  2. The application registers with APNs.
  3. iOS provides a device token when registration succeeds.
  4. The application sends the token to its backend server.
  5. The server sends a notification request to APNs.
  6. APNs delivers the notification to the device when possible.
  7. The user may tap the notification or an action button.

3. Understanding the UserNotifications Framework

The UserNotifications framework manages notification authorization, scheduling, delivery, and user interactions.

Important classes and protocols include:

API Purpose
UNUserNotificationCenter Central object for managing notification-related operations.
UNMutableNotificationContent Creates editable notification content.
UNNotificationRequest Represents a notification request.
UNTimeIntervalNotificationTrigger Schedules a notification after a time interval.
UNCalendarNotificationTrigger Schedules a notification using calendar date components.
UNNotificationResponse Represents the user's response to a notification.
UNNotificationAction Defines a custom action button.
UNNotificationCategory Groups notification actions under a category.
UNUserNotificationCenterDelegate Receives notification delivery and interaction callbacks.

4. Requesting Notification Permission

Before displaying alerts, sounds, or badges, an application should request the required notification authorization from the user.

import UserNotifications

func requestNotificationPermission() {
    let center = UNUserNotificationCenter.current()

    center.requestAuthorization(
        options: [.alert, .sound, .badge]
    ) { granted, error in

        if let error = error {
            print("Permission error: \(error)")
            return
        }

        if granted {
            print("Notification permission granted")
        } else {
            print("Notification permission denied")
        }
    }
}

The authorization options represent the notification features the application wants to use. The user makes the final decision, and permission should not be assumed to have been granted.

Checking Notification Settings

func checkNotificationSettings() {
    UNUserNotificationCenter.current()
        .getNotificationSettings { settings in

            switch settings.authorizationStatus {
            case .authorized:
                print("Notifications are authorized")

            case .denied:
                print("Notifications are denied")

            case .notDetermined:
                print("Permission has not been requested")

            case .provisional:
                print("Provisional authorization")

            case .ephemeral:
                print("Temporary authorization")

            @unknown default:
                print("Unknown authorization status")
            }
        }
}

Notification settings may change when the user updates permissions in iOS Settings. Applications should check the current settings when notification behavior matters.

5. Creating a Local Notification

A local notification is useful when an application needs to remind the user about a scheduled activity without requiring a server to send the notification.

Example: Creating Notification Content

import UserNotifications

func scheduleLocalNotification() {
    let content = UNMutableNotificationContent()

    content.title = "Task Reminder"
    content.body = "You have a task to complete."
    content.sound = .default
    content.badge = 1

    let trigger = UNTimeIntervalNotificationTrigger(
        timeInterval: 10,
        repeats: false
    )

    let request = UNNotificationRequest(
        identifier: "task-reminder",
        content: content,
        trigger: trigger
    )

    UNUserNotificationCenter.current().add(request) {
        error in

        if let error = error {
            print("Notification scheduling failed: \(error)")
        } else {
            print("Notification scheduled")
        }
    }
}

This example schedules a notification after ten seconds. The application must have suitable notification authorization for the requested presentation behavior.

6. Understanding Notification Events

A notification event occurs when a notification arrives, is displayed, or receives an interaction from the user. The application can respond differently depending on its current state and the type of interaction.

Event Delegate Method or Handling Path Purpose
Notification arrives in foreground willPresent Decide whether to display the notification and update application content.
User taps notification didReceive Process the response and navigate to relevant content.
User taps custom action didReceive Perform the selected action.
Notification opens the app from a terminated state Launch and notification response handling Restore the application and process the selected notification.
Background notification arrives Remote notification handling path Process eligible background updates when iOS allows execution.

7. Implementing UNUserNotificationCenterDelegate

The UNUserNotificationCenterDelegate protocol provides methods for handling notification events. The delegate should be assigned early in the application launch process so that notification interactions are not missed.

Example Delegate Class

import UIKit
import UserNotifications

final class NotificationManager:
    NSObject, UNUserNotificationCenterDelegate {

    static let shared = NotificationManager()

    private override init() {
        super.init()
    }

    func configure() {
        UNUserNotificationCenter.current().delegate = self
    }

    func userNotificationCenter(
        _ center: UNUserNotificationCenter,
        willPresent notification: UNNotification,
        withCompletionHandler completionHandler:
        @escaping (UNNotificationPresentationOptions) -> Void
    ) {
        print("Notification received in foreground")

        completionHandler([.banner, .sound, .badge])
    }

    func userNotificationCenter(
        _ center: UNUserNotificationCenter,
        didReceive response: UNNotificationResponse,
        withCompletionHandler completionHandler: @escaping () -> Void
    ) {
        let userInfo =
            response.notification.request.content.userInfo

        print("Notification selected: \(userInfo)")

        completionHandler()
    }
}

The foreground callback determines how an incoming notification should be presented while the application is active. The response callback processes a notification interaction, such as a tap or custom action.

8. Handling Notifications in the Foreground

When a notification arrives while the application is active, the system calls userNotificationCenter(_:willPresent:withCompletionHandler:).

The application can choose to display a banner, play a sound, update its interface, or suppress the standard notification presentation.

func userNotificationCenter(
    _ center: UNUserNotificationCenter,
    willPresent notification: UNNotification,
    withCompletionHandler completionHandler:
    @escaping (UNNotificationPresentationOptions) -> Void
) {
    let userInfo =
        notification.request.content.userInfo

    if let messageID = userInfo["message_id"] as? String {
        print("New message: \(messageID)")
    }

    completionHandler([.banner, .sound])
}

For example, a messaging application may update its conversation list when a new message arrives. It may also show a banner so that the user notices the incoming message.

9. Handling Notification Taps

When a user taps a notification, iOS invokes the notification response delegate method. The application can extract information from the notification payload and open the relevant screen.

func userNotificationCenter(
    _ center: UNUserNotificationCenter,
    didReceive response: UNNotificationResponse,
    withCompletionHandler completionHandler: @escaping () -> Void
) {
    let userInfo =
        response.notification.request.content.userInfo

    if let screen = userInfo["screen"] as? String {
        print("Open screen: \(screen)")
    }

    if let itemID = userInfo["item_id"] as? String {
        print("Open item: \(itemID)")
    }

    completionHandler()
}

In a complete application, the extracted values should be passed to a central navigation coordinator. The destination screen should be opened only after validating the identifiers and ensuring that required data is available.

10. Creating Actionable Notifications

Actionable notifications display custom buttons that allow users to perform common operations directly from the notification interface.

For example, a task management application may display buttons such as Complete and Remind Me Later.

Step 1: Define Notification Actions

let completeAction = UNNotificationAction(
    identifier: "COMPLETE_TASK",
    title: "Complete",
    options: []
)

let remindAction = UNNotificationAction(
    identifier: "REMIND_LATER",
    title: "Remind Me Later",
    options: []
)

Step 2: Create a Notification Category

let taskCategory = UNNotificationCategory(
    identifier: "TASK_CATEGORY",
    actions: [completeAction, remindAction],
    intentIdentifiers: [],
    options: []
)

UNUserNotificationCenter.current()
    .setNotificationCategories([taskCategory])

Step 3: Assign the Category to Notification Content

let content = UNMutableNotificationContent()

content.title = "Task Reminder"
content.body = "Complete your pending task."
content.categoryIdentifier = "TASK_CATEGORY"

Step 4: Process the Selected Action

func userNotificationCenter(
    _ center: UNUserNotificationCenter,
    didReceive response: UNNotificationResponse,
    withCompletionHandler completionHandler: @escaping () -> Void
) {
    switch response.actionIdentifier {

    case "COMPLETE_TASK":
        print("Task completed")

    case "REMIND_LATER":
        print("Schedule another reminder")

    case UNNotificationDefaultActionIdentifier:
        print("User opened the notification")

    case UNNotificationDismissActionIdentifier:
        print("User dismissed the notification")

    default:
        break
    }

    completionHandler()
}

Custom action identifiers should be unique and handled explicitly. If a dismissal action is required, configure the category with the appropriate custom-dismiss option.

11. Understanding Notification Payloads

A notification payload contains information that helps the application understand the event and decide what content to display.

Example Custom Payload

{
    "aps": {
        "alert": {
            "title": "New Message",
            "body": "You received a new message."
        },
        "sound": "default"
    },
    "screen": "chat",
    "conversation_id": "CHAT_102",
    "message_id": "MSG_501"
}

The aps dictionary contains Apple-defined notification information. Additional custom fields can provide application-specific context.

Do not place passwords, authentication tokens, private personal information, or other sensitive data directly in notification payloads. Use secure server-side APIs to retrieve protected content after validating the user's session.

12. Understanding Deep Linking

Deep linking allows an application to open a specific screen or resource using a URL. Instead of opening the home screen, the application can navigate directly to a product, profile, order, message, or other destination.

For example:

myapp://products/125
myapp://profile/42
myapp://orders/ORD1001

These URLs use a custom URL scheme. The application registers the scheme so iOS can route matching URLs to the app.

Benefits of Deep Linking

  • Provides direct access to specific application content.
  • Improves navigation and user experience.
  • Connects notifications with application screens.
  • Supports links shared through messages and emails.
  • Reduces the number of steps required to reach content.
  • Helps marketing campaigns direct users to relevant destinations.

13. Configuring Custom URL Schemes

A custom URL scheme is a URL format registered by an application. It can be used to open the app from another app or a link.

Configuration Steps

  1. Open the project in Xcode.
  2. Select the application target.
  3. Open the Info tab.
  4. Find URL Types.
  5. Add a new URL Type.
  6. Enter a unique URL scheme, such as myapp.
  7. Save the project configuration.

For example, the registered scheme myapp can handle links such as myapp://products/125.

Custom URL schemes are not verified by a website association. Another application may register the same scheme, so applications should not use a custom scheme as proof of the sender's identity or as a secure authorization mechanism.

14. Handling Custom URL Schemes in UIKit

UIKit applications can receive custom URL scheme links through the application delegate or scene delegate, depending on the application's lifecycle configuration.

Using AppDelegate

func application(
    _ app: UIApplication,
    open url: URL,
    options: [UIApplication.OpenURLOptionsKey: Any] = [:]
) -> Bool {

    print("Received URL: \(url)")

    handleIncomingURL(url)

    return true
}

Parsing the Incoming URL

func handleIncomingURL(_ url: URL) {
    guard url.scheme == "myapp" else {
        return
    }

    let components = url.pathComponents

    if components.count >= 3,
       components[1] == "products" {

        let productID = components[2]
        print("Open product: \(productID)")
    }
}

Always validate the scheme, host, path, and parameters before using incoming URL data.

15. Handling Deep Links in SwiftUI

SwiftUI provides the onOpenURL view modifier for receiving URLs delivered to the application.

import SwiftUI

struct ContentView: View {
    var body: some View {
        NavigationStack {
            Text("Home Screen")
                .navigationTitle("My Application")
        }
        .onOpenURL { url in
            handleIncomingURL(url)
        }
    }

    func handleIncomingURL(_ url: URL) {
        guard url.scheme == "myapp" else {
            return
        }

        print("Deep link received: \(url)")
    }
}

In a production SwiftUI application, URL parsing should usually be separated from the view. A navigation coordinator or observable application router can translate validated URLs into navigation state.

16. Understanding Universal Links

Universal Links are standard HTTPS links associated with a website and its iOS application. When correctly configured, a supported website link can open the installed application directly. If the application is not installed, the link normally opens the website.

Example:

https://www.example.com/products/125
https://www.example.com/orders/ORD1001
https://www.example.com/profile/42

Unlike custom URL schemes, Universal Links use a verified association between the application and the website's domain.

Advantages of Universal Links

  • Use normal HTTPS URLs.
  • Provide a verified website-to-application association.
  • Can open the website when the application is unavailable.
  • Support sharing links through email, messages, and websites.
  • Improve the continuity between web and app experiences.
  • Allow other applications to link to specific application content.

17. Difference Between Deep Links and Universal Links

Feature Custom URL Scheme Deep Link Universal Link
URL Format Uses a custom scheme such as myapp:// Uses standard HTTPS URLs.
Website Association Not required. Required.
Verification No website-based verification. Uses Associated Domains and an AASA file.
Fallback Requires a separately designed fallback. Can open the website when the app is unavailable.
Scheme Conflict Another app may register the same scheme. Domain association helps establish the correct app.
Example myapp://products/125 https://example.com/products/125
Common Use App-to-app navigation and legacy integrations. Website, email, messaging, and app content links.

18. Configuring Associated Domains

Universal Links require the application and website to establish a secure association.

Step 1: Enable Associated Domains

  1. Open the iOS project in Xcode.
  2. Select the application target.
  3. Open Signing & Capabilities.
  4. Add the Associated Domains capability.
  5. Add the domain using the applinks: prefix.
applinks:www.example.com

If the application supports multiple website domains, configure each required domain separately.

Step 2: Create the apple-app-site-association File

The website must host an Apple App Site Association (AASA) file. It is a JSON file that identifies the application and the website paths associated with it.

The file must be available through HTTPS at the appropriate location, commonly:

https://www.example.com/.well-known/apple-app-site-association

Example AASA File

{
    "applinks": {
        "details": [
            {
                "appIDs": [
                    "TEAMID.com.example.iosapp"
                ],
                "components": [
                    {
                        "/": "/products/*"
                    },
                    {
                        "/": "/orders/*"
                    },
                    {
                        "/": "/profile/*"
                    }
                ]
            }
        ]
    }
}

Replace the example application identifier with the actual Apple Team ID and bundle identifier. The AASA file must be served correctly, without an inappropriate file extension or redirect, and its rules must match the URLs the app intends to handle.

19. Handling Universal Links in UIKit

When a Universal Link opens an application, iOS provides an NSUserActivity object. The application can inspect its webpage URL and route the user to the corresponding content.

func application(
    _ application: UIApplication,
    continue userActivity: NSUserActivity,
    restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void
) -> Bool {

    guard userActivity.activityType ==
            NSUserActivityTypeBrowsingWeb,
          let url = userActivity.webpageURL else {
        return false
    }

    handleUniversalLink(url)

    return true
}

Processing the Universal Link

func handleUniversalLink(_ url: URL) {
    guard url.scheme == "https",
          url.host == "www.example.com" else {
        return
    }

    let components = url.pathComponents

    if components.count >= 3,
       components[1] == "products" {

        let productID = components[2]
        print("Open product: \(productID)")
    }
}

For applications using scene-based lifecycle handling, Universal Link activities may be delivered through scene connection options or the scene delegate's activity continuation method. Implement the entry points appropriate to the project's lifecycle configuration.

20. Handling Universal Links in SwiftUI

SwiftUI applications can use onOpenURL to receive incoming URLs, including supported Universal Links.

import SwiftUI

struct ContentView: View {
    var body: some View {
        NavigationStack {
            Text("Welcome")
                .navigationTitle("Home")
        }
        .onOpenURL { url in
            handleUniversalLink(url)
        }
    }

    func handleUniversalLink(_ url: URL) {
        guard url.scheme == "https",
              url.host == "www.example.com" else {
            return
        }

        print("Universal Link received: \(url)")
    }
}

The application should parse the URL and update navigation state to display the correct destination. A simple print statement is useful for testing, but production code should connect the URL handler to the application's navigation architecture.

21. Navigating to Screens Using Deep Links

Receiving a URL is only the first step. The application must convert the URL into a navigation destination.

Example: SwiftUI Product Navigation

import SwiftUI

struct Product: Identifiable, Hashable {
    let id: String
}

struct ProductHomeView: View {
    @State private var selectedProductID: String?

    var body: some View {
        NavigationStack {
            VStack {
                Text("Product Home")
            }
            .navigationDestination(
                item: $selectedProductID
            ) { productID in
                Text("Product ID: \(productID)")
            }
        }
        .onOpenURL { url in
            guard url.scheme == "myapp",
                  url.host == "products" else {
                return
            }

            let productID = url.pathComponents.last
            selectedProductID = productID
        }
    }
}

This is an illustrative navigation pattern. For a larger application, use a typed route model and a navigation path so multiple destinations and navigation states can be managed consistently. The exact navigation API should match the application's deployment target.

22. Connecting Notifications with Deep Links

One of the most useful notification features is opening a specific application screen when the user taps a notification.

For example, a notification about a new order can contain an order identifier. When the user taps it, the application opens the corresponding order details screen.

Example Notification Payload

{
    "aps": {
        "alert": {
            "title": "Order Update",
            "body": "Your order has been shipped."
        },
        "sound": "default"
    },
    "deep_link": "myapp://orders/ORD1001"
}

Extracting and Processing the Deep Link

func processNotificationResponse(
    _ response: UNNotificationResponse
) {
    let userInfo =
        response.notification.request.content.userInfo

    guard let linkString =
        userInfo["deep_link"] as? String,
        let url = URL(string: linkString) else {
        return
    }

    handleIncomingURL(url)
}

The shared URL handler should validate the URL and route it to the correct screen. Avoid implementing separate, inconsistent navigation rules for notification links and ordinary incoming links.

23. Handling Both Custom Deep Links and Universal Links

An application may support both custom URL schemes and Universal Links. A shared URL router can process both formats and convert them into the same internal route.

enum AppRoute {
    case product(String)
    case order(String)
    case profile(String)
}

func parseIncomingURL(_ url: URL) -> AppRoute? {
    let components = url.pathComponents

    if url.scheme == "myapp",
       url.host == "products",
       let productID = components.last {
        return .product(productID)
    }

    if url.scheme == "https",
       url.host == "www.example.com",
       components.count >= 3 {

        switch components[1] {
        case "products":
            return .product(components[2])

        case "orders":
            return .order(components[2])

        case "profile":
            return .profile(components[2])

        default:
            return nil
        }
    }

    return nil
}

This parser is a basic illustration. A production parser should explicitly handle URL structure, query parameters, percent encoding, malformed paths, and any supported trailing path components.

24. Handling Cold Start and Warm Start Navigation

Incoming links can arrive under different application lifecycle conditions.

Situation Description Required Handling
Cold Start The application is not currently running. Capture the incoming link during launch and process it after the navigation system is ready.
Warm Start The application is already running in the background. Process the new URL or notification response and update navigation.
Foreground The application is already visible. Navigate to the requested content without unnecessarily rebuilding the application.
Scene-Based Launch A scene is created because of an incoming activity or URL. Inspect the scene connection options and handle the incoming activity or URL.

A robust implementation should store a pending route when necessary and navigate after authentication, data loading, and initial application setup are complete.

25. Security and Validation of Incoming Links

Deep links and Universal Links are external inputs. Even when a Universal Link comes from an associated domain, its parameters should be validated before they are used.

Security Best Practices

  • Validate the URL scheme and host.
  • Allow only supported paths and query parameters.
  • Reject malformed or unexpected URLs.
  • Never trust an incoming user ID or order ID as authorization proof.
  • Verify access permissions with the backend server.
  • Avoid placing passwords and authentication tokens in URLs.
  • Use HTTPS for website links.
  • Handle expired, unavailable, or deleted content gracefully.
  • Prevent arbitrary URLs from triggering sensitive application operations.
  • Use safe fallback screens when a destination cannot be opened.

26. Testing Notifications, Deep Links, and Universal Links

Testing ensures that notification events and incoming links work correctly under different application states.

Notification Testing

  1. Request notification permission.
  2. Test the authorized and denied permission states.
  3. Schedule a local notification.
  4. Test notification delivery while the app is in the foreground.
  5. Test tapping a notification from the Lock Screen.
  6. Test custom notification action buttons.
  7. Test remote notification delivery using an APNs-enabled server or suitable development tools.
  8. Verify that notification payload values are parsed correctly.

Deep Link Testing

  1. Register the custom URL scheme in Xcode.
  2. Open a valid custom URL using the simulator or a device.
  3. Test supported and unsupported paths.
  4. Test missing and malformed identifiers.
  5. Test links while the application is running and not running.
  6. Verify that the correct screen is displayed.

Universal Link Testing

  1. Enable Associated Domains.
  2. Verify the AASA file on the website.
  3. Confirm that the application identifier is correct.
  4. Check the configured domain and path rules.
  5. Install the application on a physical device.
  6. Open a supported HTTPS link from another app or a website.
  7. Test the website fallback when the application is not installed.
  8. Verify links that should not open the application.

Universal Link behavior can be affected by the user's previous link-opening choice and system association state. Test using appropriate installation and link-opening conditions rather than assuming every tap must launch the application.

27. Common Errors and Troubleshooting

Problem Possible Cause Solution
Notification is not displayed Permission denied or notification settings disabled. Check the current authorization status and notification settings.
Foreground notification is not visible Foreground delegate method is missing or presentation options suppress the alert. Implement willPresent and return suitable presentation options.
Notification tap does not navigate Response payload is not processed. Implement didReceive and connect it to the navigation router.
Custom action does not work Category or action identifier is incorrect. Register the category and handle its exact action identifier.
Custom URL does not open the app URL scheme is missing or incorrect. Verify the URL Types configuration.
Universal Link opens Safari Associated Domains or AASA configuration is incorrect, or the user prefers the browser. Verify domain association, AASA rules, and link behavior.
Universal Link opens the wrong screen URL parsing or route mapping is incorrect. Validate host, path, and parameters before navigation.
Link works only when app is open Cold-start handling is missing. Process launch options and scene connection activities.
Notification data is missing Payload fields are absent or have unexpected types. Use safe optional parsing and inspect the actual payload.
App crashes after tapping a link Unsafe URL parsing or forced type conversion. Use safe parsing, validation, and error handling.

28. Best Practices

  • Request notification permission at a meaningful point in the user journey.
  • Assign the notification center delegate before the application finishes launching.
  • Keep notification payloads small and avoid sensitive information.
  • Use meaningful and unique notification action identifiers.
  • Always call the notification delegate completion handler.
  • Use one shared URL routing system for notifications and incoming links.
  • Prefer Universal Links for website-to-app navigation.
  • Use custom URL schemes when an application-specific scheme is required.
  • Validate every incoming URL before navigating.
  • Support cold-start and warm-start link handling.
  • Handle unavailable content and unauthenticated users gracefully.
  • Test on real devices as well as the simulator.
  • Keep notification presentation and navigation logic separate.

29. Practical Project: Notification-Based Product Navigation

Project Objective: Create an iOS shopping application that displays product notifications and opens the selected product when the user taps a notification or Universal Link.

Project Features

  • Request notification authorization.
  • Schedule local product notifications.
  • Handle notifications while the app is in the foreground.
  • Handle notification taps.
  • Extract product identifiers from notification payloads.
  • Support custom product deep links.
  • Configure Universal Links for product pages.
  • Open the correct product details screen.
  • Validate product identifiers before displaying content.

Step 1: Define the Product Route

enum AppRoute: Hashable {
    case product(String)
}

Step 2: Create a Notification Payload

let content = UNMutableNotificationContent()

content.title = "Product Update"
content.body = "A product you follow has an update."
content.userInfo = [
    "deep_link": "myapp://products/125"
]

let trigger = UNTimeIntervalNotificationTrigger(
    timeInterval: 15,
    repeats: false
)

let request = UNNotificationRequest(
    identifier: "product-update",
    content: content,
    trigger: trigger
)

UNUserNotificationCenter.current().add(request)

Step 3: Extract the Notification Link

func extractDeepLink(
    from response: UNNotificationResponse
) -> URL? {

    let userInfo =
        response.notification.request.content.userInfo

    guard let link =
        userInfo["deep_link"] as? String else {
        return nil
    }

    return URL(string: link)
}

Step 4: Parse the Product URL

func productID(from url: URL) -> String? {
    guard url.scheme == "myapp",
          url.host == "products" else {
        return nil
    }

    let components = url.pathComponents

    guard components.count == 2 else {
        return nil
    }

    let id = components[1]

    guard !id.isEmpty else {
        return nil
    }

    return id
}

Step 5: Navigate to Product Details

struct ProductDetailsView: View {
    let productID: String

    var body: some View {
        VStack {
            Text("Product Details")
                .font(.title)

            Text("Product ID: \(productID)")
        }
        .padding()
    }
}

Connect the parsed product identifier to the application's navigation path or route coordinator. Fetch the product details from the backend and verify that the signed-in user is permitted to access the requested resource.

Expected Result

When a user receives a product notification and taps it, the application extracts the product link, validates it, and navigates to the relevant product details screen. A supported Universal Link to the same product should open the same destination.

30. Practice Exercises

  1. Create an application that requests notification permission.
  2. Schedule a local notification using a time interval trigger.
  3. Implement the foreground notification delegate method.
  4. Handle notification taps using the response delegate method.
  5. Create a notification category with two custom action buttons.
  6. Build a custom URL scheme for a profile screen.
  7. Parse a URL and extract a product identifier.
  8. Configure Associated Domains for a test website.
  9. Create an AASA file for product and order paths.
  10. Implement Universal Link handling in SwiftUI.
  11. Connect a notification payload to a deep link.
  12. Test cold-start and warm-start navigation.

31. Interview Questions and Answers

Q1. What is a notification in iOS?

Answer: A notification is a system-delivered message that informs users about application events, reminders, updates, and other relevant information.

Q2. What is the difference between local and remote notifications?

Answer: Local notifications are scheduled by the application on the device, while remote notifications are sent from a server through Apple Push Notification service.

Q3. What is UNUserNotificationCenter?

Answer: It is the central API for requesting notification authorization, scheduling notifications, managing notification settings, and handling user interactions.

Q4. What is UNUserNotificationCenterDelegate?

Answer: It is a protocol used to receive callbacks when notifications arrive in the foreground or when users interact with notifications.

Q5. What is the purpose of willPresent?

Answer: It allows the application to decide how a notification should be presented while the app is running in the foreground.

Q6. What is the purpose of didReceive?

Answer: It processes user responses to delivered notifications, including taps and custom notification actions.

Q7. What is an actionable notification?

Answer: It is a notification that contains custom buttons allowing users to perform actions directly from the notification interface.

Q8. What is deep linking?

Answer: Deep linking allows an application to open a specific screen or resource using a URL rather than always opening the home screen.

Q9. What is a custom URL scheme?

Answer: It is an application-registered URL scheme, such as myapp://, that can route matching links to the application.

Q10. What are Universal Links?

Answer: Universal Links are standard HTTPS links associated with a website and its application. They can open the installed application or the website when the app is unavailable.

Q11. What is an AASA file?

Answer: The Apple App Site Association file is a JSON file hosted by a website that defines the association between the website's domain and an iOS application.

Q12. What is the Associated Domains capability?

Answer: It is an Xcode capability that declares website domains associated with an application, including domains used for Universal Links.

Q13. What is the difference between deep links and Universal Links?

Answer: Custom URL scheme deep links use an application-defined scheme and do not have website-based verification. Universal Links use HTTPS and require a verified website-to-app association.

Q14. How can a notification open a particular screen?

Answer: Include a destination identifier or supported link in the notification payload, extract it in the notification response delegate, validate it, and pass it to the navigation router.

Q15. Why should incoming URLs be validated?

Answer: Incoming URLs are external input. Validation prevents malformed links, unexpected destinations, and unauthorized access to application resources.

32. Quick Revision Checklist

  • Understand local and remote notifications.
  • Know the purpose of UserNotifications.
  • Request notification authorization correctly.
  • Check current notification settings.
  • Implement UNUserNotificationCenterDelegate.
  • Handle foreground notification delivery.
  • Process notification taps and action buttons.
  • Understand notification payloads.
  • Configure custom URL schemes.
  • Parse and validate deep links.
  • Configure Associated Domains.
  • Understand the AASA file.
  • Handle Universal Links in UIKit and SwiftUI.
  • Connect notification events to navigation.
  • Test cold-start and warm-start scenarios.
  • Apply security checks to every incoming link.

33. Conclusion

Handling notification events, deep links, and Universal Links is essential for creating connected and user-friendly iOS applications. Notifications help users stay informed, while deep links and Universal Links provide direct access to relevant application content.

The UserNotifications framework manages notification permissions, delivery, and user interactions. Custom URL schemes support application-specific deep linking, while Universal Links provide a verified connection between a website and an installed application.

By combining notification response handling, URL validation, and a centralized navigation system, developers can create reliable experiences that work across foreground, background, and cold-start application states.

34. Additional Learning Resources

Previous Next
whatsapp